package com.atguigu.mybatis.demo;

import com.atguigu.mybatis.bean.Employee;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

/**
 * Mybatis的设计思想：
 *          ①sql语句是编写在一个专门的文件中，和Java源代码文件区别
 *          ②在Java源代码文件中要使用sql
 *          ③传统的jdbc套路模板已经帮你封装了，无需再编写，直接调用mybatis封装好的方法即可。
 * JDBC的框架，原理还是JDBC。
 *               JDBC                Mybatis
 * 数据库连接    Connection          SqlSession(这个对象可以把sql发给mysql服务器)
 * ---------------------------------------------------------------------------
 *      对象的创建方式：
 *          1、直接new:    public 的构造器（无参，有参）
 *                  A a = new A()
 *          2、工厂模式：
 *                  SqlSession
 *                  A a = new AFactory().getInstance();
 *          3、建造者模式：
 *                  flink
 *                  A a = new ABulider().setASize(xxx).setAColor(xxx).build();
 *----------------------------------------------------------------------------
 * 属性的封装规则：
 *          sql:Select * from from employee where id = 1
 *          返回：
 *              id  last_name  gender  email
 *           ------  ---------  ------  -------------
 *               1      Tom      male    Tom@163.com
 *
 *          封装：根据resultType，使用反射，创建指定的Bean
 *              Employee e = new Employee()
 *
 *              某一列要封装在bean的属性上，遵守e.set列名（列值）
 *                      e.setId(1);
 *                      e.setLast_name(Tom);
 *                      e.setGender(male);
 *                      e.setEmail(Tom@163.com);
 *               解决方式：
 *                      第一种：提供setLast_name()
 *                      第二种：sql语句中起别名
 *                              select id,last_name lastName,email,gender
 *                      第三种：mybatis自动帮我把 last_name 更改为 lastName风格，起别名
 *                             通过配置：
 *                                 <settings>
 *                                      <setting name="mapUnderscoreToCamelCase" value="true"/
 *                                  </settings>
 *     ------------------------------------------------------------------------
 *       目前方式的问题：
 *          1、不符合java中面向接口开发的思想
 *                  实现功能（读写数据库）:
 *                          接口------->功能的实现
 *          2、调用的是Mybatis提供的方法，参数类型是Object，无法对入参进行类型约束和检查
 *          3、当前是泛型方法，如果不传入泛型，返回值是Object类型，还需要进行强转
 *        诉求：
 *              自己控制方法的入参类型及返回值类型，符合java面向接口开发的思想
 *
 *          解决思路：   自定义Mappper(Dao)接口，提供实现
 */
public class MybatisDemo1 {
    public static void main(String[] args) throws IOException {
        //创建 SqlSessionFactory
        String resource = "config.xml";
        InputStream inputStream = Resources   .getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //获取链接
        SqlSession sqlSession = sqlSessionFactory.openSession();
        /**
         * 使用连接
         * <T> T selectOne(String statement.Object parameter);
         * String statement:发送给mysql的sql语句。
         *                  使用namespace.id的方式去引入
         * Object parameter:sql中传入的占位符参数
         * ------------------
         * <T> T xxx():称为泛型方法
         *      在调用时：   <T>xxx()
         */
        Employee employee = sqlSession.<Employee>selectOne("feichangbang.sql1", 1);

        System.out.println(employee);

        //关闭连接
        sqlSession.close();
    }
}

//public class MybatisDemo1 {
//    public static void main(String[] args) throws IOException {
//        //创建SqlSessionFactory
//        String resource = "config.xml";
//        InputStream inputStream = Resources.getResourceAsStream(resource);
//        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//
//        //获取连接
//        SqlSession sqlSession = sqlSessionFactory.openSession();
//
//        /**
//         * 使用连接：
//         * <T> T selectOne(String statement, Object parameter);
//         * String statement:发送给mysql的sql语句
//         *              使用namespace.id的方式引入
//         * Object parameter：sql中传入的占位符参数
//         *  <T> T xxxx(): 称为泛型方法。
//         *      在调用时:   <T>xxxx()
//         */
//        Employee employee = sqlSession.<Employee>selectOne("feichangbang.sql1", resource);
//
//        System.out.println(employee);
//        //关闭连接
//        sqlSession.close();
//    }
//}

//
//public class MybatisDemo1 {
//    public static void main(String[] args) throws IOException {
//        //创建sqlSessionFactory
//        String resource = "config.xml";
//        InputStream inputStream = Resources.getResourceAsStream(resource);
//        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//
//        //获取连接
//        SqlSession sqlSession = sqlSessionFactory.openSession();
//        Employee employee = sqlSession.<Employee>selectOne("feichangbang.sql1", 1);
//
//        System.out.println(employee);
//
//        //关闭资源
//        sqlSession.close();
//    }
//}